﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Server
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //获取IP
            var hostName = Dns.GetHostName();
            var localHost = Dns.GetHostByName(hostName);
            var IP = localHost.AddressList[0];
            txtServerIP.Text = IP.ToString();

            //取消跨线程检测错误
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        #region 监听方法
        private Socket sockSend;
        private Dictionary<string, Socket> dSocket = new Dictionary<string, Socket>(); 
        private void Listen(object e)
        {
            //网络协议
            Socket socketWatch = e as Socket;

            //一直监听
            while (true)
            {
                try
                {
                    //负责跟客户端通信
                    sockSend = socketWatch.Accept();

                    //将远程连接的客户端的IP地址和Socket传入集合中
                    dSocket.Add(sockSend.RemoteEndPoint.ToString(), sockSend);

                    //将远程连接客户端的IP放入下拉框
                    cbClientIP.Items.Add(sockSend.RemoteEndPoint.ToString());

                    //自动选择到新连入的客户端
                    cbClientIP.SelectedIndex = cbClientIP.Items.IndexOf(sockSend.RemoteEndPoint.ToString());

                    ShowMessage(sockSend.RemoteEndPoint.ToString() + ": 连接成功!");

                    //开线程不断的监听客户端发送的消息
                    Thread thread = new Thread(Receive);
                    thread.IsBackground = true;
                    thread.Start(sockSend);
                }
                catch 
                {
                    MessageBox.Show("网络连接错误，请重试");
                }
            }
        }
        #endregion

        /// <summary>
        /// 服务端不断接收客户端发送的消息
        /// </summary>
        /// <param name="e"></param>
        private void Receive(object e)
        {
            //转换传入的参数类型
            while (true)
            {
                //每2m内截取一单位
                byte[] buffer = new byte[1024 * 1024 * 2];
                //实际接收的有效字节数
                int r = sockSend.Receive(buffer);
                if (r == 0)
                {
                    break;
                }
                //把二进制内容转换成字符串显示到UI
                var str = Encoding.UTF8.GetString(buffer,0,r);
                ShowMessage("客户端:" + sockSend.RemoteEndPoint + ": " + str);
            }
        }
        private void ShowMessage(string msgStr)
        {
            txtNews.AppendText(msgStr + "\r\n");
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                //当开始监听时，在服务端创建一个负责监听的IP地址和端口
                Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = IPAddress.Parse(txtServerIP.Text);

                //创建端口号对象
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));

                //开始监听
                socketWatch.Bind(point);
                ShowMessage("监听成功...");
                socketWatch.Listen(10);

                Thread thread = new Thread(Listen);
                thread.IsBackground = true;
                thread.Start(socketWatch);
            }
            catch 
            {
                MessageBox.Show("网络连接错误，请重试");
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (sockSend == null || !sockSend.Connected)
            {
                MessageBox.Show("网络连接错误，请重新连入！");
                return;
            }
            var str = txtInput.Text;
            byte[] buffer = Encoding.UTF8.GetBytes(str);
            List<byte> list = new List<byte>();
            list.Add(0);
            list.AddRange(buffer);
            byte[] newBuffer = list.ToArray();

            //获取要发送客户端的IP
            string ip = cbClientIP.SelectedItem.ToString();

            if (string.IsNullOrEmpty(ip))
            {
                MessageBox.Show("请选择客户端");
                return;
            }
            dSocket[ip].Send(newBuffer);
            txtInput.Text = "";
        }

        private void btnShake_Click(object sender, EventArgs e)
        {
            try
            {
                //获取要发送客户端的IP
                string ip = cbClientIP.SelectedItem.ToString();
                byte[] buffer = new byte[1];
                buffer[0] = 2;
                dSocket[ip].Send(buffer);
            }
            catch { }
        }

        private void btnSelect_Click(object sender, EventArgs e)
        {
            var dialog = new OpenFileDialog();
            dialog.Title = "请选择文件";
            dialog.Filter = "文本文件|*.txt|图片|*.jpg;*.png;*.gif;*.jpeg;*.bmp";
            dialog.InitialDirectory = @"G:\Gitee\CsharpAdvanced\Server";
            dialog.ShowDialog();

            txtPath.Text = dialog.FileName;
        }

        private void btnFile_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtPath.Text))
            {
                MessageBox.Show("请选择文件");
                return;
            }
            try
            {
                var path = txtPath.Text.Trim();
                string ip = cbClientIP.SelectedItem.ToString();

                using (FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read))
                {
                    byte[] buffer = new byte[1024 * 1024 * 5];
                    int r = fsRead.Read(buffer, 0, buffer.Length);

                    List<byte> list = new List<byte>();
                    list.Add(1);
                    list.AddRange(buffer);
                    byte[] newBuffer = list.ToArray();
                    dSocket[ip].Send(newBuffer,0,r+1,SocketFlags.None);
                }
            }
            catch { }
        }

        private void txtPath_TextChanged(object sender, EventArgs e)
        {
            pbPhoto.Image = System.Drawing.Image.FromFile(txtPath.Text);
        }
    }
}
